using System;
using System.IO;

namespace SharpTar
{
    public class TarFile : IDisposable
    {
        private Stream stream = null;
        private long streamPosition = 0;

        internal bool inArchive = false;

        internal TarFile(Stream stream, long streamPosition, bool inArchive = false)
        {
            this.stream = stream;
            this.streamPosition = streamPosition;
            this.inArchive = inArchive;
        }

        public TarFile(Stream stream)
        {
            this.stream = stream;
        }

        public TarFile(FileInfo file)
        {
            this.stream = file.OpenRead();
            this.header = new TarHeader();
            this.header.FileName = file.Name;
            this.header.LastModification = file.LastWriteTime;
            this.header.SizeInBytes = stream.Length;
        }

        private ITarHeader header = null;
        public ITarHeader Header
        {
            get 
            {
                return header;
            }
            set 
            {
                header = value;
            }
        }

        public TarFile()
        {
        }

        public long Read(Stream destStream)
        {
            //long totalSize = 0;

            long last_dest_pos = destStream.Position;

            long last_pos = stream.Position;
            stream.Seek(streamPosition, SeekOrigin.Begin);

            const int bufferSize = 4096;
            byte[] buffer = new byte[bufferSize];
            for (int i = 0; i * bufferSize < this.header.SizeInBytes; i++)
            {
                int remaining = (int)Math.Min(bufferSize, this.header.SizeInBytes - i*bufferSize);
                int read = stream.Read(buffer, 0, remaining);
                destStream.Write(buffer, 0, read);
                //totalSize += read;
            }

            stream.Seek(last_pos, SeekOrigin.Begin);

            destStream.Position = last_dest_pos;

            return this.header.SizeInBytes;
        }

        public void Close()
        {
            if (stream != null)
            {
                stream.Dispose();
                stream = null;
            }
        }

        #region IDisposable implementation

        public void Dispose()
        {
            Close();
        }

        #endregion
    }
}

